class Configuration {
  final double regGrayThreshold;
  final int regMaxSize;
  final int regMinSize;
  final double grayKernalSize;
  final double grayAlpha;
  final double grayBeta;
  final int grayBlurredSize;
  final int grayMaxValue;
  final int grayBlockSize;
  final double grayCThreshold;
  final bool showAreaSize;
  final bool showSpermBox;
  final bool cropFrame;
  final bool trackSpermOnly;
  final bool markRegBorder;
  final bool saveCapturedVideoToPhotos;
  final bool saveProceedImgsToPhotos;
  final bool debugMode;
  final int totalTiming;
  final int totalLiquifyingTiming;
  final String deviceIP;
  final int tempCheckInterval;
  final int matchDistance;
  final int segmentCount;
  final double segmentDuration;

  const Configuration({
    this.regGrayThreshold = 255.0,
    this.regMaxSize = 200,
    this.regMinSize = 30,
    this.grayKernalSize = 7.0,
    this.grayAlpha = 1.0,
    this.grayBeta = 5.0,
    this.grayBlurredSize = 5,
    this.grayMaxValue = 255,
    this.grayBlockSize = 37,
    this.grayCThreshold = 2.0,
    this.showAreaSize = false,
    this.showSpermBox = false,
    this.cropFrame = true,
    this.trackSpermOnly = false,
    this.markRegBorder = false,
    this.saveCapturedVideoToPhotos = true,
    this.saveProceedImgsToPhotos = false,
    this.debugMode = false,
    this.totalTiming = 300,
    this.totalLiquifyingTiming = 600,
    this.deviceIP = "192.168.3.1",
    this.tempCheckInterval = 1200,
    this.matchDistance = 28,
    this.segmentCount = 3,
    this.segmentDuration = 1.0,
  });

  Configuration copyWith({
    double? regGrayThreshold,
    int? regMaxSize,
    int? regMinSize,
    double? grayKernalSize,
    double? grayAlpha,
    double? grayBeta,
    int? grayBlurredSize,
    int? grayMaxValue,
    int? grayBlockSize,
    double? grayCThreshold,
    bool? showAreaSize,
    bool? showSpermBox,
    bool? cropFrame,
    bool? trackSpermOnly,
    bool? markRegBorder,
    bool? saveCapturedVideoToPhotos,
    bool? saveProceedImgsToPhotos,
    bool? debugMode,
    int? totalTiming,
    int? totalLiquifyingTiming,
    String? deviceIP,
    int? tempCheckInterval,
    int? matchDistance,
    int? segmentCount,
    double? segmentDuration,
  }) {
    return Configuration(
      regGrayThreshold: regGrayThreshold ?? this.regGrayThreshold,
      regMaxSize: regMaxSize ?? this.regMaxSize,
      regMinSize: regMinSize ?? this.regMinSize,
      grayKernalSize: grayKernalSize ?? this.grayKernalSize,
      grayAlpha: grayAlpha ?? this.grayAlpha,
      grayBeta: grayBeta ?? this.grayBeta,
      grayBlurredSize: grayBlurredSize ?? this.grayBlurredSize,
      grayMaxValue: grayMaxValue ?? this.grayMaxValue,
      grayBlockSize: grayBlockSize ?? this.grayBlockSize,
      grayCThreshold: grayCThreshold ?? this.grayCThreshold,
      showAreaSize: showAreaSize ?? this.showAreaSize,
      showSpermBox: showSpermBox ?? this.showSpermBox,
      cropFrame: cropFrame ?? this.cropFrame,
      trackSpermOnly: trackSpermOnly ?? this.trackSpermOnly,
      markRegBorder: markRegBorder ?? this.markRegBorder,
      saveCapturedVideoToPhotos: saveCapturedVideoToPhotos ?? this.saveCapturedVideoToPhotos,
      saveProceedImgsToPhotos: saveProceedImgsToPhotos ?? this.saveProceedImgsToPhotos,
      debugMode: debugMode ?? this.debugMode,
      totalTiming: totalTiming ?? this.totalTiming,
      totalLiquifyingTiming: totalLiquifyingTiming ?? this.totalLiquifyingTiming,
      deviceIP: deviceIP ?? this.deviceIP,
      tempCheckInterval: tempCheckInterval ?? this.tempCheckInterval,
      matchDistance: matchDistance ?? this.matchDistance,
      segmentCount: segmentCount ?? this.segmentCount,
      segmentDuration: segmentDuration ?? this.segmentDuration,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'regGrayThreshold': regGrayThreshold,
      'regMaxSize': regMaxSize,
      'regMinSize': regMinSize,
      'grayKernalSize': grayKernalSize,
      'grayAlpha': grayAlpha,
      'grayBeta': grayBeta,
      'grayBlurredSize': grayBlurredSize,
      'grayMaxValue': grayMaxValue,
      'grayBlockSize': grayBlockSize,
      'grayCThreshold': grayCThreshold,
      'showAreaSize': showAreaSize,
      'showSpermBox': showSpermBox,
      'cropFrame': cropFrame,
      'trackSpermOnly': trackSpermOnly,
      'markRegBorder': markRegBorder,
      'saveCapturedVideoToPhotos': saveCapturedVideoToPhotos,
      'saveProceedImgsToPhotos': saveProceedImgsToPhotos,
      'debugMode': debugMode,
      'totalTiming': totalTiming,
      'totalLiquifyingTiming': totalLiquifyingTiming,
      'deviceIP': deviceIP,
      'tempCheckInterval': tempCheckInterval,
      'matchDistance': matchDistance,
      'segmentCount': segmentCount,
      'segmentDuration': segmentDuration,
    };
  }

  factory Configuration.fromJson(Map<String, dynamic> json) {
    return Configuration(
      regGrayThreshold: json['regGrayThreshold']?.toDouble() ?? 255.0,
      regMaxSize: json['regMaxSize']?.toInt() ?? 200,
      regMinSize: json['regMinSize']?.toInt() ?? 30,
      grayKernalSize: json['grayKernalSize']?.toDouble() ?? 7.0,
      grayAlpha: json['grayAlpha']?.toDouble() ?? 1.0,
      grayBeta: json['grayBeta']?.toDouble() ?? 5.0,
      grayBlurredSize: json['grayBlurredSize']?.toInt() ?? 5,
      grayMaxValue: json['grayMaxValue']?.toInt() ?? 255,
      grayBlockSize: json['grayBlockSize']?.toInt() ?? 37,
      grayCThreshold: json['grayCThreshold']?.toDouble() ?? 2.0,
      showAreaSize: json['showAreaSize'] ?? false,
      showSpermBox: json['showSpermBox'] ?? false,
      cropFrame: json['cropFrame'] ?? true,
      trackSpermOnly: json['trackSpermOnly'] ?? false,
      markRegBorder: json['markRegBorder'] ?? false,
      saveCapturedVideoToPhotos: json['saveCapturedVideoToPhotos'] ?? true,
      saveProceedImgsToPhotos: json['saveProceedImgsToPhotos'] ?? false,
      debugMode: json['debugMode'] ?? false,
      totalTiming: json['totalTiming']?.toInt() ?? 300,
      totalLiquifyingTiming: json['totalLiquifyingTiming']?.toInt() ?? 600,
      deviceIP: json['deviceIP'] ?? "192.168.3.1",
      tempCheckInterval: json['tempCheckInterval']?.toInt() ?? 1200,
      matchDistance: json['matchDistance']?.toInt() ?? 28,
      segmentCount: json['segmentCount']?.toInt() ?? 3,
      segmentDuration: json['segmentDuration']?.toDouble() ?? 1.0,
    );
  }

  @override
  String toString() {
    return 'Configuration(regGrayThreshold: $regGrayThreshold, regMaxSize: $regMaxSize, regMinSize: $regMinSize, grayKernalSize: $grayKernalSize, grayAlpha: $grayAlpha, grayBeta: $grayBeta, grayBlurredSize: $grayBlurredSize, grayMaxValue: $grayMaxValue, grayBlockSize: $grayBlockSize, grayCThreshold: $grayCThreshold, showAreaSize: $showAreaSize, showSpermBox: $showSpermBox, cropFrame: $cropFrame, trackSpermOnly: $trackSpermOnly, markRegBorder: $markRegBorder, saveCapturedVideoToPhotos: $saveCapturedVideoToPhotos, saveProceedImgsToPhotos: $saveProceedImgsToPhotos, debugMode: $debugMode, totalTiming: $totalTiming, totalLiquifyingTiming: $totalLiquifyingTiming, deviceIP: $deviceIP, tempCheckInterval: $tempCheckInterval, matchDistance: $matchDistance, segmentCount: $segmentCount, segmentDuration: $segmentDuration)';
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is Configuration &&
        other.regGrayThreshold == regGrayThreshold &&
        other.regMaxSize == regMaxSize &&
        other.regMinSize == regMinSize &&
        other.grayKernalSize == grayKernalSize &&
        other.grayAlpha == grayAlpha &&
        other.grayBeta == grayBeta &&
        other.grayBlurredSize == grayBlurredSize &&
        other.grayMaxValue == grayMaxValue &&
        other.grayBlockSize == grayBlockSize &&
        other.grayCThreshold == grayCThreshold &&
        other.showAreaSize == showAreaSize &&
        other.showSpermBox == showSpermBox &&
        other.cropFrame == cropFrame &&
        other.trackSpermOnly == trackSpermOnly &&
        other.markRegBorder == markRegBorder &&
        other.saveCapturedVideoToPhotos == saveCapturedVideoToPhotos &&
        other.saveProceedImgsToPhotos == saveProceedImgsToPhotos &&
        other.debugMode == debugMode &&
        other.totalTiming == totalTiming &&
        other.totalLiquifyingTiming == totalLiquifyingTiming &&
        other.deviceIP == deviceIP &&
        other.tempCheckInterval == tempCheckInterval &&
        other.matchDistance == matchDistance &&
        other.segmentCount == segmentCount &&
        other.segmentDuration == segmentDuration;
  }

  // @override
  // int get hashCode {
  //   return Object.hash(
  //     regGrayThreshold,
  //     regMaxSize,
  //     regMinSize,
  //     grayKernalSize,
  //     grayAlpha,
  //     grayBeta,
  //     grayBlurredSize,
  //     grayMaxValue,
  //     grayBlockSize,
  //     grayCThreshold,
  //     showAreaSize,
  //     showSpermBox,
  //     cropFrame,
  //     trackSpermOnly,
  //     markRegBorder,
  //     saveCapturedVideoToPhotos,
  //     saveProceedImgsToPhotos,
  //     debugMode,
  //     totalTiming,
  //     totalLiquifyingTiming,
  //     deviceIP,
  //     tempCheckInterval,
  //     matchDistance,
  //     segmentCount,
  //     segmentDuration,
  //   );
  // }
}
